﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Xww.LCV.Model {
    public static class LinkedListTool {
        public static LinkedListNode<string> OffsetNext(this LinkedListNode<string> node, int offset) {
            for (int i = 0; i < offset; i++) {
                node = node.Next;
                if (node == null) {
                    throw new IndexOutOfRangeException("Offset value out of range @ OffsetNode");
                }
            }
            return node;
        }
        public static LinkedListNode<string> OffsetPrevious(this LinkedListNode<string> node, int offset) {
            for (int i = 0; i < offset; i++) {
                node = node.Previous;
                if (node == null) {
                    throw new IndexOutOfRangeException("Offset value out of range @ OffsetNode");
                }
            }
            return node;
        }
        public static string ConcatString(this LinkedListNode<string> first, LinkedListNode<string> last) {
            StringBuilder rst = new StringBuilder();

            var node = first;
            while (node != last) {
                if (node == null) {
                    throw new ArgumentException("Unexpected ending @ ConcatString");
                }
                rst.AppendFormat("{0} ", node.Value);
                node = node.Next;
            }
            rst.Append(node.Value);
            return rst.ToString();
        }

        public static string ConcatString(this LinkedListNode<string> first, LinkedListNode<string> last, bool isMiddleEmpty) {
            StringBuilder rst = new StringBuilder();
            var node = first;
            int position = 0;
            while (node != last) {
                if (node == null) {
                    throw new ArgumentException("Unexpected ending @ ConcatString");}
                position++;
                string cotent = node.Value;
                if (isMiddleEmpty && node != first && node != last) { // 指针到链表中端，且中端可以设置为空时。
                }
                else {
                    rst.AppendFormat("{0}{1} ", cotent, position);
                }
                node = node.Next;
            }
            rst.AppendFormat("{0}{1}", last.Value, position+1);
            return rst.ToString();
        }
        public static bool IsFirst(this LinkedListNode<string> node) {
            return node.Previous == null;
        }
        public static bool IsLast(this LinkedListNode<string> node) {
            return node.Next == null;
        }
        public static IEnumerable<LinkedListNode<T>> MoveAllNext<T>(this IEnumerable<LinkedListNode<T>> nodes) {
            return nodes.Where( o => o.Next != null).Select(o => o.Next);
        }
        public static int CountOfNode<T>(this IEnumerable<LinkedListNode<T>> nodes, int steps, T value) where T:IEquatable<T> {
            int rst = 0,i;
            foreach (var item in nodes) {
                var currentNode = item;
                for (i = 0; i < steps; i++) {
                    currentNode = currentNode.Next;
                    if (currentNode == null)
                        break;
                }
                if (i == steps && currentNode.Value.Equals(value))
                    ++rst;
            }
            return rst;
        }
        /*
        public static int CountOfNode<T>(this IEnumerable<LinkedListNode<T>> nodes, LCS reference) where T : IEquatable<T> {
            int rst = 0,i;
            foreach (var item in nodes) {
                var currentNode = item;
                bool goNext = true;
                for (int index = 1; goNext && index < reference.Length; ++index) {
                    int steps = reference[index].Location - reference[index - 1].Location;
                    for (i = 0; i < steps; i++) {
                        currentNode = currentNode.Next;
                        if (currentNode == null)
                            break;
                    }
                    if (i == steps && currentNode.Value.Equals(reference[index].AA))
                        goNext = true;
                    else
                        goNext = false;
                }
                if (goNext)
                    rst++;
            }
            return rst;
        }
        */
    }

}
